package com.ym.b2b.payment.controller.allinPay;

import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.allinpay.ets.client.SecurityUtil;
import com.ym.b2b.commons.conf.B2BConstants;
import com.ym.b2b.commons.conf.WebTokenUser;
import com.ym.b2b.commons.controller.BaseController;
import com.ym.b2b.commons.util.CheckData;
import com.ym.b2b.order.dao.EmSOrderDao;
import com.ym.b2b.order.sqlbean.EmSOrder;
import com.ym.b2b.order.vo.OrderInfoVO;
import com.ym.b2b.payment.service.EmSPaymentService;
import com.ym.b2b.payment.sqlbean.EmSPayment;
import com.ym.b2b.payment.vo.PaymentBean;
import com.ym.b2b.user.dao.EmCUserDAO;
import com.ym.b2b.user.sqlbean.EmCUser;
import com.zc.commons.base.Result;

@Controller
@RequestMapping("/allinPay")
public class AllinPayController extends BaseController {

	/**
	 * 在tk/config/spring/med-context-bank中配置
	 * 测试时使用 InquiryParam
	 */
    @Resource
    private AllinParam        allinParamBean;

/*    @Resource
    private InquiryParam        allinParamBean;*/
    
    @Autowired
    private EmSOrderDao       emSOrderDao;

    @Autowired
    private EmCUserDAO        emCUserDAO;

    @Autowired
    private EmSPaymentService emSPaymentService;

    /**
     * 通联支付
     * 订单列表点在线支付-->立即付款
     */
    @RequestMapping("getAllinPayInfoForFee.s")
    public ModelAndView getAllinPayInfoForFee(EmSOrder emSOrder, HttpServletRequest req) {
        ModelAndView m = new ModelAndView();
        try {

            WebTokenUser token = getWebTokenUser(req);
            if (null == token) {
                m.setViewName(B2BConstants.WEB_NOT_LOGIN);
                return m;
            }
            // 组装需要塞入的订单信息
            EmSOrder s = emSOrderDao.searchOrderDetail(emSOrder);
            if (null == s || s.getStatus() >= 20) {
                m.addObject("info", "订单已经支付过了  不能重复提交!");
                m.setViewName(B2BConstants.WEB_ERROR);
                return m;
            }

            AllinParam allinParam = new AllinParam();
            BeanUtils.copyProperties(allinParam, allinParamBean);
            // allinParam = allinParamBean;
            System.out.println("单例调试：" + allinParam.getSignMsg());
            System.out.println(JSON.toJSONString(allinParam));
            EmCUser emCUser = new EmCUser();
            emCUser.setUserId(token.getUserId());
            emCUser = emCUserDAO.searchEmCUser(emCUser);

            allinParam.setPayerName(emCUser.getUserName());
            allinParam.setPayerEmail(emCUser.getEmail());
            allinParam.setPayerTelephone(emCUser.getTelePhone());
            // allinParam.setPayerIDCard(emCUser.get);身份证号

            allinParam.setPaymentMoney(s.getConfirmMoney());
            Double money = s.getConfirmMoney() * 100;

            allinParam.setOrderAmount(Long.parseLong(money.toString().split("\\.")[0]));
            allinParam.setOrderNo(s.getOrderCode());
            // 填充支付
            PaymentBean emSPaymentBean = new PaymentBean();
            emSPaymentBean.setOrderCode(s.getOrderCode());
            emSPaymentBean.setPaymentRequestIp(CheckData.getIpAddr(req));
            emSPaymentBean.setPaymentMoney(s.getConfirmMoney());
            Result ret = emSPaymentService.doPayBefore(emSPaymentBean);

            if (ret.getCode().equals("100")) {
                m.addObject("info", "订单支付请求 提交失败 请联系管理员!");
                m.setViewName(B2BConstants.WEB_ERROR);
                return m;
            }

            EmSPayment p = (EmSPayment) ret.getData("emSPayment");

            allinParam.setExt1(String.valueOf(p.getPaymentId()));
            SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddhhmmss");
            allinParam.setOrderDatetime(sf.format(new Date()));

            allinParam.setSignMsg(getSignMsg(allinParam, req));

            m.addObject("allinParam", allinParam);
            System.out.println("发送到支付网站的数据");
            System.out.println(JSON.toJSONString(allinParam));
            m.setViewName("/center/trade/pay/allinpay/post_do");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            m.setViewName(B2BConstants.WEB_ERROR);
        }
        return m;

    }

    // 把B的 属性复制给A
    private void putBeanProperty(AllinParam a, AllinParam b) throws IllegalAccessException, InvocationTargetException {
        BeanUtils.copyProperties(a, b);
    }

    private String getSignMsg(AllinParam allin, HttpServletRequest req) {

        // 若直连telpshx渠道，payerTelephone、payerName、payerIDCard、pan四个字段不可为空
        // 其中payerIDCard、pan需使用公钥加密（PKCS1格式）后进行Base64编码
        if (null != allin.getPayerIDCard() && !"".equals(allin.getPayerIDCard())) {
            try {
                // payerIDCard = SecurityUtil.encryptByPublicKey("C:\\TLCert.cer", payerIDCard);
                allin.setPayerIDCard(SecurityUtil.encryptByPublicKey(req.getRealPath("/views/jsp/center/trade/pay/allinpay/") + "/TLCert-test.cer", allin.getPayerIDCard()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (null != allin.getPan() && !"".equals(allin.getPan())) {
            try {
                allin.setPan(SecurityUtil.encryptByPublicKey(req.getRealPath("/views/jsp/center/trade/pay/allinpay/") + "/TLCert-test.cer", allin.getPan()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // 构造订单请求对象，生成signMsg。
        com.allinpay.ets.client.RequestOrder requestOrder = new com.allinpay.ets.client.RequestOrder();
        if (null != allin.getInputCharset() && !"".equals(allin.getInputCharset())) {
            requestOrder.setInputCharset(Integer.parseInt(allin.getInputCharset()));
        }
        requestOrder.setPickupUrl(allin.getPickupUrl());
        requestOrder.setReceiveUrl(allin.getReceiveUrl());
        requestOrder.setVersion(allin.getVersion());
        if (null != allin.getLanguage() && !"".equals(allin.getLanguage())) {
            requestOrder.setLanguage(Integer.parseInt(allin.getLanguage()));
        }
        requestOrder.setSignType(Integer.parseInt(allin.getSignType()));
        requestOrder.setPayType(Integer.parseInt(allin.getPayType()));
        requestOrder.setIssuerId(allin.getIssuerId());
        requestOrder.setMerchantId(allin.getMerchantId());
        requestOrder.setPayerName(allin.getPayerName());
        requestOrder.setPayerEmail(allin.getPayerEmail());
        requestOrder.setPayerTelephone(allin.getPayerTelephone());
        requestOrder.setPayerIDCard(allin.getPayerIDCard());
        requestOrder.setPid(allin.getPid());
        requestOrder.setOrderNo(allin.getOrderNo());
        requestOrder.setOrderAmount(allin.getOrderAmount().longValue());
        requestOrder.setOrderCurrency(allin.getOrderCurrency());
        requestOrder.setOrderDatetime(allin.getOrderDatetime());
        requestOrder.setOrderExpireDatetime(allin.getOrderExpireDatetime());
        requestOrder.setProductName(allin.getProductName());
        if (null != allin.getProductPrice() && !"".equals(allin.getProductPrice())) {
            requestOrder.setProductPrice(Long.parseLong(allin.getProductPrice()));
        }
        if (null != allin.getProductNum() && !"".equals(allin.getProductNum())) {
            requestOrder.setProductNum(Integer.parseInt(allin.getProductNum()));
        }
        requestOrder.setProductId(allin.getProductId());
        requestOrder.setProductDesc(allin.getProductDesc());
        requestOrder.setExt1(allin.getExt1());
        requestOrder.setExt2(allin.getExt2());
        requestOrder.setExtTL(allin.getExtTL());// 通联商户拓展业务字段，在v2.2.0版本之后才使用到的，用于开通分账等业务
        requestOrder.setPan(allin.getPan());
        requestOrder.setTradeNature(allin.getTradeNature());
        requestOrder.setKey(allin.getKey()); // key为MD5密钥，密钥是在通联支付网关会员服务网站上设置。

        String strSrcMsg = requestOrder.getSrc().trim(); // 此方法用于debug，测试通过后可注释。
        logger.info("通联  加密测试：" + strSrcMsg);
        return requestOrder.doSign();
    }

    @RequestMapping("recviceAllinPay.s")
    public void recviceAllinPay(AllinReceiveBean receiveBean, HttpServletRequest req) {
        try {

            System.out.println("接收回调参数：" + receiveBean);

            if (receiveBean.getSignType().equals("1")) {
                // signType为"1"时，必须设置证书路径。
                receiveBean.setCertPath(req.getRealPath("/views/jsp/center/trade/pay/allinpay/") + "/TLCert-test.cer");
            }
            // 验证签名：返回true代表验签成功；否则验签失败。
            boolean verifyResult = receiveBean.verify();

            // 验签成功，还需要判断订单状态，为"1"表示支付成功。
            boolean paySuccess = verifyResult && receiveBean.getPayResult().equals("1");

            if (paySuccess) {
                // TODO 商户订单处理
                // 更新订单状态 和 支付表数据
                SimpleDateFormat sf = new SimpleDateFormat("yyyyMMDDhhmmss");

                EmSOrder order = new EmSOrder();
                order.setOrderCode(receiveBean.getOrderNo());
                order.setStatus(Double.parseDouble("20"));
                order.setFeeDate(receiveBean.getPayDatetime());
                order.setTranSerialNo(receiveBean.getPaymentOrderId());
                order.setFeeAmount(Double.parseDouble(receiveBean.getPayAmount()) / 100);
                order.setOrderType(1);
                emSOrderDao.updateEmSOrder(order);

                EmSPayment payment = new EmSPayment();
                payment.setPaymentId(Long.parseLong(receiveBean.getExt1()));

                payment.setPaymentFrom("PC");
                payment.setPaymentMedthod("通联");
                payment.setPaymentMoney(Double.parseDouble(receiveBean.getPayAmount()) / 100);
                payment.setPaymentCompleteDate(sf.parse(receiveBean.getPayDatetime()));
                payment.setTranSerialNo(receiveBean.getPaymentOrderId());
                payment.setPaymentStatus(1);
                payment.setDealFlag(1);

                emSPaymentService.updateEmSPayment(payment);

                System.out.println("商户订单处理完成");
            } else {
                System.out.println("商户订单处理失败");
            }

            System.out.println("Server接收处理完成");
        } catch (Exception e) {
            e.printStackTrace();

        }

    }

    /**
     * 支付接口 *****重要******
     * 
     * @Title: feeOrder
     */
    @RequestMapping(value = "feeOrder.s")
    public ModelAndView feeOrder(String orderCode, HttpServletRequest req) {

        ModelAndView m = new ModelAndView();
        Result ret = new Result();
        try {
            WebTokenUser tokenUser = getWebTokenUser(req);
            if (tokenUser == null) {
                m.setViewName(B2BConstants.WEB_NOT_LOGIN);
                return m;
            }
            OrderInfoVO vo = new OrderInfoVO();
            vo.setOrderCode(orderCode);

            m.addObject("ret", ret);
            if (ret.getCode().equals(Result.CODE_100)) {
                m.setViewName("forward:/views/jsp/center/trade/shoppingcart/c_shopping_cart_list.jsp");
                return m;
            }

            m.setViewName("forward:/views/jsp/center/trade/order/c_order_list.jsp");
        } catch (Exception e) {
            ret.setCodeResult(Result.CODE_100, e.getMessage());
            m.addObject("ret", ret);
            m.setViewName("forward:/views/jsp/center/trade/shoppingcart/c_shopping_cart_list.jsp");

        }
        return m;
    }

}
